package com.ruoyi.app.controller.business.statistics;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruoyi.business.base.PageParam;
import com.ruoyi.business.customer.domain.JbCustomer;
import com.ruoyi.business.customer.domain.JbFollowupRecord;
import com.ruoyi.business.customer.domain.JbOpportunity;
import com.ruoyi.business.customer.service.JbCustomerService;
import com.ruoyi.business.customer.service.JbFollowupRecordService;
import com.ruoyi.business.customer.service.JbOpportunityService;
import com.ruoyi.business.order.domain.JbOrder;
import com.ruoyi.business.order.domain.JbOrderCommodity;
import com.ruoyi.business.order.domain.JbPaymentReceived;
import com.ruoyi.business.order.service.JbOrderCommodityService;
import com.ruoyi.business.order.service.JbOrderService;
import com.ruoyi.business.order.service.JbPaymentReceivedService;
import com.ruoyi.business.sundry.domain.JbPerformance;
import com.ruoyi.business.sundry.domain.vo.JbStatisticsPerformanceVo;
import com.ruoyi.business.sundry.service.JbPerformanceService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.controller.business.audit.factory.JbAuditFactory;
import com.ruoyi.web.controller.system.factory.SysDataScopeFactory;
import com.ruoyi.web.core.JoR;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 绩效 Controller
 *
 * @author ruoyi
 * @date 2024-10-11
 */
@Api("绩效")
@RestController
@RequestMapping("/app/statistics/performance")
public class AppJbPerformanceController extends BaseController
{
    @Autowired
    private JbPerformanceService service;
    @Autowired
    private JbOrderService jbOrderService;
    @Autowired
    private JbOrderCommodityService jbOrderCommodityService;
    @Autowired
    private JbPaymentReceivedService paymentReceivedService;
    @Autowired
    private JbCustomerService jbCustomerService;
    @Autowired
    private JbOpportunityService jbOpportunityService;
    @Autowired
    private JbFollowupRecordService jbFollowupRecordService;
    @Autowired
    private JbAuditFactory jbAuditFactory;
    @Autowired
    private SysDataScopeFactory sysDataScopeFactory;

    /**
     * 查询年度目标和完成
     */
    @ApiOperation("查询年度目标和完成")
    @GetMapping("/yearList")
    public AjaxResult yearPerformanceList(PageParam pageParam,JbPerformance jbPerformance)
    {
        Long userId = getUserId();
        jbPerformance.setFinancialYear(StringUtils.isNotBlank(jbPerformance.getFinancialYear()) ?
                jbPerformance.getFinancialYear()
                : String.valueOf(LocalDateTime.now().getYear()));
        jbPerformance.setTargetType(StringUtils.isNotBlank(jbPerformance.getTargetType()) ?
                jbPerformance.getTargetType()
                : Constants.CUSTOMER_TYPE_1001);
        jbPerformance.setPerformanceType(ObjectUtils.isNotEmpty(jbPerformance.getPerformanceType()) ?
                jbPerformance.getPerformanceType()
                : Constants.PUBLIC_NUMBER_2);
        JbStatisticsPerformanceVo vo = new JbStatisticsPerformanceVo();
        JbPerformance one = service.getOne(Wrappers.lambdaQuery(JbPerformance.class)
                .eq(JbPerformance::getFinancialYear, jbPerformance.getFinancialYear())
                .eq(JbPerformance::getTargetType, jbPerformance.getTargetType())
                .eq(ObjectUtils.isNotEmpty(jbPerformance.getDepartment()), JbPerformance::getDepartment,
                        jbPerformance.getDepartment())
                .eq(ObjectUtils.isNotEmpty(jbPerformance.getRelatedId()), JbPerformance::getRelatedId,
                        jbPerformance.getRelatedId())
                .eq(JbPerformance::getPerformanceType, jbPerformance.getPerformanceType())
                .eq(JbPerformance::getRelatedId, userId), false);
        vo.setAnnualTarget(ObjectUtils.isNotEmpty(one) ? one.getAnnualTarget() : BigDecimal.ZERO);
        // 订单完成数量
        String type=pageParam.getKeyword();
        LocalDateTime[] times = DateUtils.getTimes(Constants.CUSTOMER_TYPE_1001);
        if (Constants.CUSTOMER_TYPE_1009.equals(type))
        {
            times = DateUtils.getTimes(Constants.CUSTOMER_TYPE_1009);
        }else if (Constants.CUSTOMER_TYPE_1005.equals(type))
        {
            times = DateUtils.getTimes(Constants.CUSTOMER_TYPE_1005);
        }
        String createTime = String.format("AND create_time>= '%s'  AND create_time<= '%s'", times[0], times[1]);
        QueryWrapper<JbOrder> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(order_total_amount) as orderTotalAmount ");
        orderWrapper.lambda().eq(JbOrder::getCreateBy, userId)
                .eq(JbOrder::getIsProcessEnd, Constants.PUBLIC_NUMBER_1)//财务审批完的订单
                .last(createTime);
        JbOrder jbOrderOne = jbOrderService.getOne(orderWrapper, false);
        vo.setTotalAmount(BigDecimal.ZERO);
        if (ObjectUtils.isNotEmpty(jbOrderOne) && ObjectUtils.isNotEmpty(jbOrderOne.getOrderTotalAmount()))
        {
            vo.setTotalAmount(jbOrderOne.getOrderTotalAmount());
        }
        vo.getConversionRateCompute();
        return success(vo);
    }


    /**
     * 查询月度目标和完成
     */
    @ApiOperation("查询月度目标和完成")
    @GetMapping("/monthList")
    public AjaxResult monthList(JbPerformance jbPerformance,PageParam param)
    {
        List<Long> userIds = Lists.newArrayList();
        Long userId = getUserId();
        StringBuilder stringBuilder=new StringBuilder();
        String last="";
        if (ObjUtil.isNotNull(jbPerformance.getDepartment()))
        {
            stringBuilder.append(String.format("""
                    select user_id from sys_user t1 INNER JOIN sys_dept t2 on t1.dept_id=t2.dept_id  
                    										where  t2.del_flag=0
                    										and t2.del_flag=0  and ( t2.dept_id=%s or find_in_set(%s, t2.ancestors ))
                    """, jbPerformance.getDepartment(), jbPerformance.getDepartment()));
            userId=null;
        }
        if (ObjUtil.isNotNull(param.getIds()))
        {
            //ids转逗号拼接string
            userIds=param.getIds();
            userId=null;
        }
        if (ObjUtil.isNotNull(userId))
        {
            userIds.add(userId);
        }
        jbPerformance.setFinancialYear(StringUtils.isNotBlank(jbPerformance.getFinancialYear()) ?
                jbPerformance.getFinancialYear()
                : String.valueOf(LocalDateTime.now().getYear()));
        jbPerformance.setTargetType(StringUtils.isNotBlank(jbPerformance.getTargetType()) ?
                jbPerformance.getTargetType()
                : Constants.CUSTOMER_TYPE_1001);
        if (stringBuilder.length()>0)
        {
            last = String.format("and related_id in (%s)", stringBuilder);
        }
        JbPerformance one = service.getOne(Wrappers.lambdaQuery(JbPerformance.class)
                .eq(JbPerformance::getFinancialYear, jbPerformance.getFinancialYear())
                .eq(JbPerformance::getTargetType, jbPerformance.getTargetType())
                .eq(JbPerformance::getPerformanceType, Constants.PUBLIC_NUMBER_2)
                        .in(JbPerformance::getRelatedId, userId,ObjUtil.isNotEmpty(userIds))
                        .last(last)
                , false);
        List<JbStatisticsPerformanceVo> voList = Lists.newArrayList();
        if (ObjUtil.isNull(one))
        {
            one=new JbPerformance();
        }
        // 按月订单完成数量
        if (stringBuilder.length()>0)
        {
            last = String.format(" and create_by in (%s)", stringBuilder);
        }
        QueryWrapper<JbOrder> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(order_total_amount) as orderTotalAmount,count(1) as create_by " +
                ",DATE_FORMAT(create_time, '%Y-%m' ) as remark");
        orderWrapper.lambda()
                .in(JbOrder::getCreateBy, userId,ObjUtil.isNotEmpty(userIds))
                .eq(JbOrder::getIsProcessEnd, Constants.PUBLIC_NUMBER_1)//财务审批完的订单
                .last("and YEAR(create_time)=" + jbPerformance.getFinancialYear()
                        +last
                        + " group by DATE_FORMAT( create_time, '%Y-%m' ) order by orderTotalAmount desc");
        List<JbOrder> jbOrderList = jbOrderService.list(orderWrapper);
        Map<String, JbOrder> orderMap = jbOrderList.stream().collect(Collectors.toMap(JbOrder::getRemark,
                Function.identity()));

        for (int i = 1; i <= 12; i++)
        {
            JbStatisticsPerformanceVo vo = new JbStatisticsPerformanceVo();
            String s = String.format("%d-%02d", Integer.valueOf(jbPerformance.getFinancialYear()), i);
            vo.setTime(s);
            JbOrder jbOrder = orderMap.get(s);
            if (ObjectUtils.isNotEmpty(jbOrder))
            {
                vo.setTotalAmount(jbOrder.getOrderTotalAmount());
                vo.setTotalCount(jbOrder.getCreateBy().intValue());
                vo.setAverage(jbOrder.getOrderTotalAmount().divide(new BigDecimal(jbOrder.getCreateBy())
                        , 2, BigDecimal.ROUND_HALF_UP));
            }
            vo.setAnnualTarget(switch (i)
            {
                case 1 -> one.getJanuary();
                case 2 -> one.getFebruary();
                case 3 -> one.getMarch();
                case 4 -> one.getApril();
                case 5 -> one.getMay();
                case 6 -> one.getJune();
                case 7 -> one.getJuly();
                case 8 -> one.getAugust();
                case 9 -> one.getSeptember();
                case 10 -> one.getOctober();
                case 11 -> one.getNovember();
                case 12 -> one.getDecember();
                default -> BigDecimal.ZERO;
            });
            vo.getConversionRateCompute();
            voList.add(vo);
        }
        return success(voList);
    }

    /**
     * 订单统计 待确定是否用
     *
     * @param jbPerformance
     * @return
     */
    private Map<String, JbStatisticsPerformanceVo> getOrderList(JbPerformance jbPerformance)
    {
        QueryWrapper<JbOrder> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(order_total_amount) as orderTotalAmount,count(1) as create_by " +
                ",DATE_FORMAT(create_time, '%Y-%m' ) as remark");
        orderWrapper.lambda().eq(JbOrder::getCreateBy, getUserId())
                .eq(JbOrder::getIsProcessEnd, Constants.PUBLIC_NUMBER_1)//财务审批完的订单
                .last("and YEAR(create_time)=" + jbPerformance.getFinancialYear()
                        + " group by DATE_FORMAT( create_time, '%Y-%m' ) order by orderTotalAmount desc");

        List<JbOrder> jbList = jbOrderService.list(orderWrapper);
        Map<String, JbStatisticsPerformanceVo> dataMap = Maps.newHashMap();
        jbList.forEach(a ->
        {
            JbStatisticsPerformanceVo vo = new JbStatisticsPerformanceVo();
            vo.setTime(a.getRemark());
            vo.setTotalAmount(a.getOrderTotalAmount());
            vo.setTotalCount(a.getCreateBy().intValue());
            vo.setAverage(a.getOrderTotalAmount().divide(new BigDecimal(a.getCreateBy())
                    , 2, BigDecimal.ROUND_HALF_UP));
            dataMap.put(a.getRemark(), vo);
        });
        return dataMap;
    }

    /**
     * 回款统计 待确定是否用
     *
     * @param jbPerformance
     * @return
     */
    private Map<String, JbStatisticsPerformanceVo> getPaymentList(JbPerformance jbPerformance)
    {

        QueryWrapper<JbPaymentReceived> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(payment_amount) as paymentAmount,count(1) as create_by " +
                ",DATE_FORMAT(create_time, '%Y-%m' ) as remark");
        orderWrapper.lambda().eq(JbPaymentReceived::getCreateBy, getUserId())
                .last("and YEAR(create_time)=" + jbPerformance.getFinancialYear()
                        + " group by DATE_FORMAT( create_time, '%Y-%m' ) order by paymentAmount desc");
        List<JbPaymentReceived> jbList = paymentReceivedService.list(orderWrapper);
        Map<String, JbStatisticsPerformanceVo> dataMap = Maps.newHashMap();
        jbList.forEach(a ->
        {
            JbStatisticsPerformanceVo vo = new JbStatisticsPerformanceVo();
            vo.setTime(a.getRemark());
            vo.setTotalAmount(a.getPaymentAmount());
            vo.setTotalCount(a.getCreateBy().intValue());
            vo.setAverage(a.getPaymentAmount().divide(new BigDecimal(a.getCreateBy())
                    , 2, BigDecimal.ROUND_HALF_UP));
            dataMap.put(a.getRemark(), vo);
        });
        return dataMap;
    }

    /**
     * 个人部门业绩排名
     */
    @ApiOperation("个人部门业绩排名")
    @GetMapping("/personageList")
    public TableDataInfo personageList(PageParam param, JbPerformance jbPerformance)
    {
        IPage<JbStatisticsPerformanceVo> page = service.appPersonageList(param, jbPerformance);
        return JoR.getDataTable(page);
    }

    /**
     * 个人成交统计
     */
    @ApiOperation("个人成交统计")
    @GetMapping("/personageData")
    public AjaxResult personageDealList(PageParam param, JbPerformance jbPerformance)
    {
        Long userId = getUserId();
        QueryWrapper<JbOrder> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(order_total_amount) as orderTotalAmount ,count(1) as remark");
        orderWrapper.lambda()
                .eq(JbOrder::getCreateBy, userId)
                .eq(JbOrder::getIsProcessEnd, Constants.PUBLIC_NUMBER_1)//财务审批完的订单
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()), JbOrder::getCreateTime, param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder()), JbOrder::getCreateTime, param.getEndTimeBuilder());
        JbOrder jbOrderList = jbOrderService.getOne(orderWrapper);
        // 获取订单商品数量
        JbOrderCommodity commodity = new JbOrderCommodity();
        commodity.setCreateBy(userId);
        int commodityCount = jbOrderCommodityService.getOrderCommodityCount(param, commodity);
        BigDecimal orderTotalAmount = ObjectUtils.isNotEmpty(jbOrderList.getOrderTotalAmount())
                ? jbOrderList.getOrderTotalAmount() : BigDecimal.ZERO;
        BigDecimal orderCount = StringUtils.isNotBlank(jbOrderList.getRemark())
                ? new BigDecimal(jbOrderList.getRemark()) : BigDecimal.ZERO;
        Map<String, Object> data = Maps.newHashMap();
        data.put("orderTotalAmount", orderTotalAmount);
        data.put("orderCount", orderCount);
        data.put("commodityCount", commodityCount);
        BigDecimal average=BigDecimal.ZERO;
        if (orderTotalAmount.compareTo(BigDecimal.ZERO)>0 && orderCount.compareTo(BigDecimal.ZERO)>0)
        {
            average=orderTotalAmount.divide(orderCount, 2, BigDecimal.ROUND_HALF_UP);
        }
        data.put("average", average);
        return success(data);
    }

    /**
     * 个人部门成交排名统计
     */
    @ApiOperation("个人部门成交排名统计")
    @GetMapping("/personageOrderList")
    public TableDataInfo personageOrderList(PageParam param, JbPerformance jbPerformance)
    {
        IPage<JbStatisticsPerformanceVo> page = service.appPersonageOrderList(param, jbPerformance);
        return JoR.getDataTable(page);
    }

    /**
     * 个人回款数据
     */
    @ApiOperation("个人回款排名数据")
    @GetMapping("/personageReceivablesData")
    public AjaxResult personageReceivablesData(PageParam param, JbPerformance jbPerformance)
    {
        QueryWrapper<JbPaymentReceived> orderWrapper = new QueryWrapper();
        orderWrapper.select(" sum(payment_amount) as paymentAmount ,count(1) as remark");
        orderWrapper.lambda()
                .eq(JbPaymentReceived::getCreateBy, getUserId())
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()), JbPaymentReceived::getCreateTime,
                        param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder()), JbPaymentReceived::getCreateTime, param.getEndTimeBuilder());
        JbPaymentReceived jbOrderList = paymentReceivedService.getOne(orderWrapper);
        Map<String, Object> data = Maps.newHashMap();
        data.put("totalAmount", jbOrderList.getPaymentAmount());
        data.put("totalCount", jbOrderList.getRemark());
        return success(data);
    }

    /**
     * 个人部门回款排名统计
     */
    @ApiOperation("个人部门回款排名统计")
    @GetMapping("/personageReceivablesList")
    public TableDataInfo personageReceivablesList(PageParam param, JbPerformance jbPerformance)
    {
        IPage<JbStatisticsPerformanceVo> page = service.appPersonageReceivablesList(param, jbPerformance);
        return JoR.getDataTable(page);
    }


    /**
     * 业务新增数据
     */
    @ApiOperation("业务新增数据")
    @GetMapping("/businessAddData")
    public AjaxResult businessAddData(PageParam param, JbPerformance jbPerformance)
    {
        // 新增商机
        long customerAdd = jbOpportunityService.count(Wrappers.lambdaQuery(JbOpportunity.class)
                .eq(JbOpportunity::getCreateBy, getUserId())
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()), JbOpportunity::getCreateTime, param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder()), JbOpportunity::getCreateTime, param.getEndTimeBuilder()));
        // 新增客户
        long followUpAdd = jbCustomerService.count(Wrappers.lambdaQuery(JbCustomer.class)
                .eq(JbCustomer::getCreateBy, getUserId())
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()), JbCustomer::getCreateTime, param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder()), JbCustomer::getCreateTime, param.getEndTimeBuilder()));
        // 新增订单
        long orderAdd = jbOrderService.count(Wrappers.lambdaQuery(JbOrder.class)
                .eq(JbOrder::getCreateBy, getUserId())
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()), JbOrder::getCreateTime, param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder()), JbOrder::getCreateTime, param.getEndTimeBuilder()));
        Map<String, Object> data = Maps.newHashMap();
        data.put("customerAdd", customerAdd);
        data.put("followUpAdd", followUpAdd);
        data.put("orderAdd", orderAdd);
        return success(data);
    }

    /**
     * 时间汇总
     */
    @ApiOperation("时间汇总")
    @GetMapping("/businessTimeList")
    public AjaxResult businessTimeList(PageParam param, JbStatisticsPerformanceVo jbPerformance)
    {
        List<JbStatisticsPerformanceVo> page = service.appBusinessTimeList(param, jbPerformance);
        return success(page);
    }

    /**
     * 人员汇总
     */
    @ApiOperation("人员汇总")
    @GetMapping("/businessPersonageList")
    public TableDataInfo businessPersonageList(PageParam param, JbStatisticsPerformanceVo jbPerformance)
    {
        IPage<JbStatisticsPerformanceVo> page = service.businessPersonageList(param, jbPerformance);
        return JoR.getDataTable(page);
    }

    /**
     * 待办事项列表
     */
    @ApiOperation("待办事项列表")
    @GetMapping("/backlogItemList")
    public AjaxResult backlogItemList(PageParam param, JbStatisticsPerformanceVo jbPerformance)
    {
        // 跟进计划 查询为完成的
        Long userId = getUserId();
        //角色数据权限
        List<Long> roleData=sysDataScopeFactory.fnListDataScope(Constants.PUBLIC_NUMBER_0.toString());
        long followupCount = jbFollowupRecordService.count(Wrappers.lambdaQuery(JbFollowupRecord.class)
                // .in(ObjectUtils.isNotEmpty(roleData),JbFollowupRecord::getStaffId,roleData)
                .eq(JbFollowupRecord::getStaffId, userId)
                .eq(JbFollowupRecord::getDataType, Constants.PUBLIC_NUMBER_0)
                .eq(JbFollowupRecord::getTaskStatus, Constants.JBFOLLOWUPRECORD_TASKSTATUS_1003)
                .ge(StringUtils.isNotBlank(param.getStartTimeBuilder()),
                        JbFollowupRecord::getFollowupTime, param.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(param.getEndTimeBuilder())
                        , JbFollowupRecord::getFollowupTime, param.getEndTimeBuilder()));

        // 待办查询，目前查全量的
        JSONObject taskCount = jbAuditFactory.taskListStatistics(param);
        taskCount.put("followupCount", followupCount);
        return success(taskCount);
    }
}
